;//
;// startup.s
;// Usage: Startup code for NewLife OS Loader. MultiBootHeader
;// Create Date: 2009-01-31
;// Creator: MaJiuyue
;//
%include "sconst.inc"

global startup         ; making entry point visible to linker
global stack
extern nfldr           ; nfldr is defined elsewhere
extern kinit
extern start_ctors
extern end_ctors
extern __cxa_finalize

; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ  1<<0                   ; align loaded modules on page boundaries
MEMINFO     equ  1<<1                   ; provide memory map
FLAGS       equ  MODULEALIGN | MEMINFO  ; this is the Multiboot 'flag' field
MAGIC       equ    0x1BADB002           ; 'magic number' lets bootloader find the header
CHECKSUM    equ -(MAGIC + FLAGS)        ; checksum required

section .text
align 4
MultiBootHeader:
   dd MAGIC
   dd FLAGS
   dd CHECKSUM

; reserve initial loader stack space
STACKSIZE equ 0x1000                  ; that's 4k.

startup:
   mov esp, stack+STACKSIZE           ; set up the stack

   push eax                           ; pass Multiboot magic number
   push ebx                           ; pass Multiboot info structure
   call  nfldr                        ; call kernel loader

   ; We have already map a 16K-length stack at linear address 0xEFFC000 to
   ; 0xEFFFFFF, and we have nothing usefull in the OLD-STACK, so change it
   ; to higher address we map in `nfldr'
;   mov esp, TopOfKernelStack 

static_ctors_loop:
   mov ebx, start_ctors
   jmp .test
.body:
   call [ebx]
   add ebx,4
.test:
   cmp ebx, end_ctors
   jb .body

   call kinit                         ; call kernel init

   call __cxa_finalize

   hlt                                ; halt machine should kernel return

section .bss
align 32
stack:
   resb STACKSIZE                     ; reserve 16k stack on a quadword boundary

